package com.free.job.task;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.free.common.core.constant.RedisSystemCacheConstants;
import com.free.common.core.utils.SpringUtils;
import com.free.common.core.utils.StringUtils;
import com.free.common.core.web.domain.R;
import com.free.common.core.web.page.TableDataInfo;
import com.free.system.api.RemoteNoteService;
import com.free.system.api.RemoteRecognitionService;
import com.free.system.api.RemoteUserService;
import com.free.system.api.domain.ZoneNote;
import com.huaweicloud.sdk.image.v2.model.ImageTaggingItemBody;
import com.huaweicloud.sdk.image.v2.model.ImageTaggingReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

import static org.apache.poi.openxml4j.opc.ContentTypes.IMAGE_PNG;

/**
 * 定时任务调度测试
 *
 * @author free
 */
@Slf4j
@Component
public class RyTask {
    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    String[] types = {"success", "info", "warning", "danger"};
    String[] color = {"#BFEFFF", "#b344db", "#2132ea"};


    /**
     * 讯飞语音识别文件上传
     */
    public void xfAudioFileUpload() throws InterruptedException {
        log.info("开始讯飞语音识别文件上传");
        RemoteNoteService remoteNoteService = SpringUtils.getBean(RemoteNoteService.class);
        RemoteRecognitionService remoteRecognitionService = SpringUtils.getBean(RemoteRecognitionService.class);
        ZoneNote zoneNote = new ZoneNote();
        zoneNote.setAiAudioToText(1);
        List<ZoneNote> zoneNotes = remoteNoteService.listInner(zoneNote);
        if (ObjectUtil.isNotEmpty(zoneNotes)) {
            for (ZoneNote note : zoneNotes) {
                log.info("需要执行的文件:"+note);
                Thread.sleep(2000L);
                R<String> stringR = remoteRecognitionService.xfAudioUpload(note.getFilePath());
                log.info("文件上传返回："+stringR.getData().toString());
                if (stringR.getCode() == 200) {
                    if (ObjectUtil.isNotEmpty(stringR.getData())) {
                        note.setXfOrderId(stringR.getData());
                        R<String> contentResult = remoteRecognitionService.xfAudioGetContent(stringR.getData());
                        log.info("内容返回："+contentResult.getData());
                        if (contentResult.getCode() == 200) {
                            while (ObjectUtil.isEmpty(contentResult.getData())) {
                                Thread.sleep(1000L);
                                log.info("内容返回："+contentResult.getData());
                                contentResult = remoteRecognitionService.xfAudioGetContent(stringR.getData());
                            }
                            note.setAiAudioToText(3);
                            note.setContent(new String(Base64Utils.encode(contentResult.getData().getBytes())));
                        } else {
                            note.setAiAudioToText(4);
                        }
                    } else {
                        note.setAiAudioToText(4);
                    }
                    remoteNoteService.edit(note);
                }
            }
        }

    }

    /**
     * 讯飞语音识别文件上传
     */
    public void baiduAudio() throws InterruptedException {
        log.info("开始百度语音识别文件上传");
        RemoteNoteService remoteNoteService = SpringUtils.getBean(RemoteNoteService.class);
        RemoteRecognitionService remoteRecognitionService = SpringUtils.getBean(RemoteRecognitionService.class);
        ZoneNote zoneNote = new ZoneNote();
        zoneNote.setAiAudioToText(1);
        List<ZoneNote> zoneNotes = remoteNoteService.listInner(zoneNote);
        if (ObjectUtil.isNotEmpty(zoneNotes)) {
            for (ZoneNote note : zoneNotes) {
                log.info("需要执行的文件:"+note);
                Thread.sleep(2000L);
                R<String> stringR = remoteRecognitionService.baiduCreate(note.getFilePath());
                log.info("任务创建："+stringR.getData().toString());
                if (stringR.getCode() == 200) {
                    if (ObjectUtil.isNotEmpty(stringR.getData())) {
                        note.setXfOrderId(stringR.getData());
                        R<String> contentResult = remoteRecognitionService.baiduAudioGetContent(stringR.getData());
                        log.info("内容返回："+contentResult.getData());
                        if (contentResult.getCode() == 200) {
                            while (ObjectUtil.isEmpty(contentResult.getData())) {
                                Thread.sleep(1000L);
                                log.info("内容返回："+contentResult.getData());
                                contentResult = remoteRecognitionService.xfAudioGetContent(stringR.getData());
                            }
                            note.setAiAudioToText(3);
                            note.setContent(new String(Base64Utils.encode(contentResult.getData().getBytes())));
                        } else {
                            note.setAiAudioToText(4);
                        }
                    } else {
                        note.setAiAudioToText(4);
                    }
                    remoteNoteService.edit(note);
                }
            }
        }

    }

    /**
     * 对文件进行归档处理
     */
    public void fileSynchronization() {
        log.info("开始文件同步");
        RemoteNoteService remoteNoteService = SpringUtils.getBean(RemoteNoteService.class);
        ZoneNote needRecognitionOne = remoteNoteService.getNeedFileSynchronization().getData();
        if (needRecognitionOne == null) {
            return;
        }
        needRecognitionOne.setUpdateTime(new Date());

    }
    public void getNeedRecognitionOne() throws IOException {
        log.info("开始识别");
        RemoteNoteService remoteNoteService = SpringUtils.getBean(RemoteNoteService.class);
         String TEM_FILE_PATH = "/audio/temp.file";
        ZoneNote needRecognitionOne = remoteNoteService.getNeedRecognitionOne().getData();
        if (needRecognitionOne == null) {
            return;
        }
        needRecognitionOne.setUpdateTime(new Date());

        RemoteRecognitionService remoteRecognitionService = SpringUtils.getBean(RemoteRecognitionService.class);
        ImageTaggingReq imageTaggingReq = new ImageTaggingReq();
        //下载文件
//        String filePath = new String(Base64Utils.decodeFromString(needRecognitionOne.getContent())).replace("/statics", "").replace("//", "/").replace("\\statics", "").replace("\\\\", "\\");
//        Ftp ftp = new Ftp("192.168.2.120");
        File file = new File(TEM_FILE_PATH);
//        ftp.download(filePath, file);
//        ftp.close();
        HttpUtil.downloadFile("192.168.2.77" + new String(Base64.decode(needRecognitionOne.getContent().getBytes())), file);
        try {
            recursionCompress(imageTaggingReq, file);
//        imageTaggingReq.setUrl("http://yhl.zone/"+new String(Base64Utils.decodeFromString(needRecognitionOne.getContent())));
            R<List<ImageTaggingItemBody>> res = remoteRecognitionService.recognitionImages(imageTaggingReq);
            List<ImageTaggingItemBody> data = res.getData();
            if (res.getCode() != 200) {
                needRecognitionOne.setAiRecognition(1);
            } else {
                needRecognitionOne.setAiRecognition(2);
            }

            List<Map> tags = new ArrayList<>();
            if (ObjectUtil.isNotEmpty(data)) {
                data.forEach(e -> {
                    Map<String, String> tagMap = new HashMap<>();
                    tagMap.put("name", e.getTag());
                    tagMap.put("type", types[RandomUtil.randomInt(0, types.length)]);
                    tagMap.put("color", color[RandomUtil.randomInt(0, color.length)]);
                    tags.add(tagMap);
                });
                needRecognitionOne.setTag(JSONUtil.toJsonStr(tags));
            }
        } catch (Exception e) {
            e.printStackTrace();
            needRecognitionOne.setAiRecognition(3);
        }
        //更新数据库
        remoteNoteService.edit(needRecognitionOne);
        file.delete();
        System.out.println("执行getNeedRecognitionOne--->" + needRecognitionOne);
    }

    /**
     * 递归压缩
     */
    public void recursionCompress(ImageTaggingReq imageTaggingReq, File file) throws IOException {

        FileInputStream fileInputStream = new FileInputStream(file);
        int available = fileInputStream.available();
        byte[] bytes = new byte[available];
        log.info("图片大小-->" + available);
        fileInputStream.read(bytes);
        imageTaggingReq.setImage(Base64Utils.encodeToString(bytes));
        log.info("压缩后-->" + imageTaggingReq.getImage());
        fileInputStream.close();
        //开始图片压缩
        if (available > 1878240) {
//            compressJpgAngJpegImage(new FileInputStream(file), new FileOutputStream(file), 0.9F, "jpg");
            // 这一行通过输入流将图片读取为 BufferedImage 对象
            BufferedImage image = ImageIO.read(new FileInputStream(file));

            // 获取特定格式的图像写入器（比如JPG JPEG），并获取默认的写入参数，用于设置图像的压缩方式和质量
            ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").next();

            ImageWriteParam param = writer.getDefaultWriteParam();

            // 设置压缩模式为 MODE_EXPLICIT，表示要显式地设置压缩参数,通过 setCompressionQuality() 方法设置压缩质量
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(0.5F);

            // 输入图片并关闭
            writer.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(file)));
            writer.write(null, new IIOImage(image, null, null), param);
            writer.dispose();
            recursionCompress(imageTaggingReq, file);
        }
    }

    /**
     * 压缩jpg和jpeg图片
     *
     * @param inputStream   图片输入流
     * @param outputStream  图片输入流
     * @param compressRatio 压缩率
     * @param extensionName 拓展名
     */
    public static void compressJpgAngJpegImage(FileInputStream inputStream, FileOutputStream outputStream,
                                               float compressRatio, String extensionName) throws IOException {
        // 这一行通过输入流将图片读取为 BufferedImage 对象
        BufferedImage image = ImageIO.read(inputStream);

        // 获取特定格式的图像写入器（比如JPG JPEG），并获取默认的写入参数，用于设置图像的压缩方式和质量
        ImageWriter writer = ImageIO.getImageWritersByFormatName(extensionName).next();
        ImageWriteParam param = writer.getDefaultWriteParam();

        // 设置压缩模式为 MODE_EXPLICIT，表示要显式地设置压缩参数,通过 setCompressionQuality() 方法设置压缩质量
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(compressRatio);

        // 输入图片并关闭
        writer.setOutput(ImageIO.createImageOutputStream(outputStream));
        writer.write(null, new IIOImage(image, null, null), param);
        writer.dispose();
    }

    /**
     * 压缩png图片
     *
     * @param inputStream   图片输入流
     * @param outputStream  图片输入流
     * @param compressRatio 压缩率
     */
    public static void compressPngImage(InputStream inputStream, OutputStream outputStream, float compressRatio) throws IOException {
        BufferedImage inputImage = ImageIO.read(inputStream);

        // 获取压缩因子
        float factor = 1 / compressRatio;

        int originWidth = inputImage.getWidth();
        int originHeight = inputImage.getHeight();

        // 压缩率计算压缩尺寸
        int tempWidth = (int) (originWidth / factor);
        int tempHeight = (int) (originHeight / factor);

        // 缩小尺寸
        BufferedImage outputImage = new BufferedImage(tempWidth, tempHeight, BufferedImage.TYPE_INT_ARGB);
        outputImage.getGraphics().drawImage(inputImage.getScaledInstance(tempWidth, tempHeight, BufferedImage.SCALE_SMOOTH), 0, 0, null);

        // 恢复原始尺寸
        BufferedImage compressedImage = new BufferedImage(originWidth, originHeight, BufferedImage.TYPE_INT_ARGB);
        compressedImage.getGraphics().drawImage(outputImage.getScaledInstance(originWidth, originHeight, BufferedImage.SCALE_SMOOTH), 0, 0, null);

        ImageIO.write(compressedImage, IMAGE_PNG, outputStream);
    }

    public void pushNote() throws IOException {
        log.info("开始推送");
        RemoteNoteService remoteNoteService = SpringUtils.getBean(RemoteNoteService.class);
        RemoteUserService remoteUserService = SpringUtils.getBean(RemoteUserService.class);
        RedisTemplate redisTemplate = SpringUtils.getBean("redisTemplate");
        TableDataInfo listR = remoteUserService.userList();
        log.info("获取到的所有用户：{}", JSONUtil.toJsonStr(listR));
        listR.getRows().forEach(user -> {
            JSONObject jsonObject = JSONObject.parseObject(JSONUtil.toJsonStr(user));
            log.info(String.valueOf(jsonObject));

            if (1 == jsonObject.getLong("needPush")) {
                Long userId = jsonObject.getLong("userId");
                R res = remoteNoteService.randomOne();
                log.info("获取到的code:{}", res.getCode());
                log.info("获取到的msg:{}", res.getData());
                log.info("获取到的data:{}", res.getMsg());
                JSONObject entries = JSONObject.parseObject(JSONUtil.toJsonStr(res.getData()));
                //接口对内容由大小限制
                entries.replace("content", System.currentTimeMillis());
                //redis获取cid
                Set members = redisTemplate.opsForSet().members(RedisSystemCacheConstants.getPushUserCidSet(userId));
                log.info("用户：{}获取到的cid：{}", userId, members);
                if (ObjectUtil.isNotEmpty(members)) {
                    members.forEach(cid -> {
                        entries.put("cid", cid);
                        log.info("推送给用户的消息:" + entries.toJSONString());
                        String post = HttpUtil.post("https://fc-mp-142a7e4b-3724-4ddd-aed8-cdf54d0a46d2.next.bspapp.com/pushNote", entries.toJSONString());
                        log.info("调用云函数的返回值：" + post);
                    });
                }

            }

        });
    }


}
